"""
FastMCP ActionRequiredLogger Tool
==================================

This module implements a FastMCP tool called ActionRequiredLogger that allows
large language models to submit email processing tasks to the EmailQA system
via function calls.

The tool receives email data and forwards it to the email pending task API endpoint.
Supports both stdio and HTTP transport modes.
"""

import json
import logging
from typing import Dict, Any, Optional
from mcp.server.fastmcp import FastMCP
import requests
from requests.exceptions import RequestException
from flask import Flask, request, jsonify

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Initialize FastMCP server
mcp = FastMCP("EmailQA ActionRequiredLogger")

# Initialize Flask app for HTTP mode
http_app = Flask(__name__)

class ActionRequiredLogger:
    """
    MCP Tool for logging email action requirements to the EmailQA system.
    
    This tool provides a function call interface for LLMs to submit email
    processing tasks to the pending task system.
    """
    
    def __init__(self, use_test_client: bool = False):
        """
        Initialize the ActionRequiredLogger tool.
        
        Args:
            use_test_client: Whether to use Flask test client (True) or HTTP requests (False)
        """
        self.use_test_client = use_test_client
        if not use_test_client:
            self.api_base_url = "http://localhost:5000"
            self.api_endpoint = f"{self.api_base_url}/api/email_pending_task/"
        
    def submit_email_task(
        self,
        email_id: str,
        email_info_json: str,
        sop_json: str,
        generated_reply: str,
        action_type: str
    ) -> Dict[str, Any]:
        """
        Submit an email processing task to the EmailQA system.
        
        Args:
            email_id: Email identifier (e.g., user@example.com)
            email_info_json: Email information in JSON format
            sop_json: Standard operating procedure in JSON format
            generated_reply: Generated reply text
            action_type: Type of action performed (e.g., 'reply', 'forward', 'escalate')
            
        Returns:
            Dictionary containing the API response or error information
        """
        try:
            # Validate required parameters
            if not all([email_id, email_info_json, sop_json, generated_reply, action_type]):
                missing_params = []
                if not email_id:
                    missing_params.append("email_id")
                if not email_info_json:
                    missing_params.append("email_info_json")
                if not sop_json:
                    missing_params.append("sop_json")
                if not generated_reply:
                    missing_params.append("generated_reply")
                if not action_type:
                    missing_params.append("action_type")
                
                return {
                    "success": False,
                    "error": f"Missing required parameters: {', '.join(missing_params)}"
                }
            
            # Prepare the request payload
            payload = {
                "email_id": email_id,
                "task_id": f"mcp_{hash(email_id + action_type)}",  # Generate unique task ID
                "email_info_json": email_info_json,
                "sop_json": sop_json,
                "generated_reply": generated_reply,
                "action_type": action_type,
                "created_by": "mcp_action_required_logger"
            }
            
            # Make request to the EmailQA API
            if self.use_test_client:
                # Use Flask test client
                logger.info(f"Submitting email task for {email_id} using test client")
                
                import sys
                sys.path.append('src')
                from src.interfaces.api_with_docs import app
                
                with app.test_client() as client:
                    response = client.post('/api/email_pending_task/', json=payload)
                    
                if response.status_code == 201:
                    result = response.get_json()
                    logger.info(f"Successfully submitted task for {email_id}, task_id: {result.get('task_id')}")
                    return {
                        "success": True,
                        "message": "Email task submitted successfully",
                        "task_id": result.get("task_id"),
                        "data": result.get("data", {})
                    }
                else:
                    error_msg = f"API request failed with status {response.status_code}"
                    try:
                        error_data = response.get_json()
                        error_msg += f": {error_data.get('error', 'Unknown error')}"
                    except:
                        error_msg += f": {response.get_data(as_text=True)}"
                    
                    logger.error(f"Failed to submit task for {email_id}: {error_msg}")
                    return {
                        "success": False,
                        "error": error_msg,
                        "status_code": response.status_code
                    }
            else:
                # Use HTTP requests
                logger.info(f"Submitting email task for {email_id} to {self.api_endpoint}")
                
                response = requests.post(
                    self.api_endpoint,
                    json=payload,
                    headers={"Content-Type": "application/json"},
                    timeout=30  # 30 second timeout
                )
                
                # Process the response
                if response.status_code == 201:
                    result = response.json()
                    logger.info(f"Successfully submitted task for {email_id}, task_id: {result.get('task_id')}")
                    return {
                        "success": True,
                        "message": "Email task submitted successfully",
                        "task_id": result.get("task_id"),
                        "data": result.get("data", {})
                    }
                else:
                    error_msg = f"API request failed with status {response.status_code}"
                    try:
                        error_data = response.json()
                        error_msg += f": {error_data.get('error', 'Unknown error')}"
                    except ValueError:
                        error_msg += f": {response.text}"
                    
                    logger.error(f"Failed to submit task for {email_id}: {error_msg}")
                    return {
                        "success": False,
                        "error": error_msg,
                        "status_code": response.status_code
                    }
                
        except json.JSONDecodeError as e:
            logger.error(f"JSON decode error: {e}")
            return {
                "success": False,
                "error": f"Invalid JSON format: {str(e)}"
            }
        except RequestException as e:
            logger.error(f"Network error: {e}")
            return {
                "success": False,
                "error": f"Network error: {str(e)}"
            }
        except Exception as e:
            logger.error(f"Unexpected error: {e}")
            return {
                "success": False,
                "error": f"Unexpected error: {str(e)}"
            }

# Create tool instance
action_logger = ActionRequiredLogger()

# Register the tool with FastMCP
@mcp.tool()
def action_required_logger(
    email_id: str,
    email_info_json: str,
    sop_json: str,
    generated_reply: str,
    action_type: str
) -> str:
    """
    Submit an email processing task to the EmailQA system.
    
    This tool allows large language models to submit email action requirements
    to the EmailQA pending task system for processing and tracking.
    
    Args:
        email_id: Email identifier (e.g., "user@example.com")
        email_info_json: Email information in JSON format containing details like subject, sender, etc.
        sop_json: Standard operating procedure in JSON format defining the processing steps
        generated_reply: The generated reply text for the email
        action_type: Type of action performed (e.g., "reply", "forward", "escalate", "review")
    
    Returns:
        JSON string containing the submission result with success status and task information
    """
    result = action_logger.submit_email_task(
        email_id=email_id,
        email_info_json=email_info_json,
        sop_json=sop_json,
        generated_reply=generated_reply,
        action_type=action_type
    )
    
    return json.dumps(result, indent=2, ensure_ascii=False)

@mcp.tool()
def check_api_health() -> str:
    """
    Check the health status of the EmailQA API.
    
    Returns:
        JSON string containing the API health status
    """
    try:
        if action_logger.use_test_client:
            # Use Flask test client
            import sys
            sys.path.append('src')
            from src.interfaces.api_with_docs import app
            
            with app.test_client() as client:
                response = client.get('/api/health/')
                
            if response.status_code == 200:
                health_data = response.get_json()
                return json.dumps({
                    "success": True,
                    "api_healthy": True,
                    "health_data": health_data
                }, indent=2, ensure_ascii=False)
            else:
                return json.dumps({
                    "success": False,
                    "api_healthy": False,
                    "error": f"API returned status {response.status_code}"
                }, indent=2, ensure_ascii=False)
        else:
            # Use HTTP requests
            health_url = f"{action_logger.api_base_url}/api/health/"
            response = requests.get(health_url, timeout=10)
            
            if response.status_code == 200:
                health_data = response.json()
                return json.dumps({
                    "success": True,
                    "api_healthy": True,
                    "health_data": health_data
                }, indent=2, ensure_ascii=False)
            else:
                return json.dumps({
                    "success": False,
                    "api_healthy": False,
                    "error": f"API returned status {response.status_code}"
                }, indent=2, ensure_ascii=False)
            
    except Exception as e:
        return json.dumps({
            "success": False,
            "api_healthy": False,
            "error": f"Failed to check API health: {str(e)}"
        }, indent=2, ensure_ascii=False)

# HTTP API endpoints for MCP tool
@http_app.route('/api/mcp/action_required_logger', methods=['POST'])
def http_action_required_logger():
    """
    HTTP endpoint for the action_required_logger tool.
    
    This allows clients to call the MCP tool via HTTP requests.
    """
    try:
        data = request.get_json()
        if not data:
            return jsonify({
                "success": False,
                "error": "Missing JSON data in request"
            }), 400
        
        # Extract required parameters
        email_id = data.get('email_id')
        email_info_json = data.get('email_info_json')
        sop_json = data.get('sop_json')
        generated_reply = data.get('generated_reply')
        action_type = data.get('action_type')
        
        # Call the tool function
        result = action_logger.submit_email_task(
            email_id=email_id,
            email_info_json=email_info_json,
            sop_json=sop_json,
            generated_reply=generated_reply,
            action_type=action_type
        )
        
        # Return the result
        status_code = 200 if result.get('success') else 400
        return jsonify(result), status_code
        
    except Exception as e:
        logger.error(f"HTTP endpoint error: {e}")
        return jsonify({
            "success": False,
            "error": f"Internal server error: {str(e)}"
        }), 500

@http_app.route('/api/mcp/check_health', methods=['GET'])
def http_check_health():
    """
    HTTP endpoint for checking the health of the EmailQA API.
    """
    try:
        result = json.loads(check_api_health())
        return jsonify(result)
    except Exception as e:
        logger.error(f"Health check error: {e}")
        return jsonify({
            "success": False,
            "error": f"Health check failed: {str(e)}"
        }), 500

@http_app.route('/api/mcp/tools', methods=['GET'])
def list_tools():
    """
    HTTP endpoint to list available MCP tools.
    """
    return jsonify({
        "success": True,
        "tools": [
            {
                "name": "action_required_logger",
                "description": "Submit email processing tasks to the EmailQA system",
                "endpoint": "/api/mcp/action_required_logger",
                "method": "POST"
            },
            {
                "name": "check_api_health",
                "description": "Check the health status of the EmailQA API",
                "endpoint": "/api/mcp/check_health",
                "method": "GET"
            }
        ]
    })

def run_http_server(host='localhost', port=8080, debug=False):
    """
    Run the MCP tool as an HTTP server.
    
    Args:
        host: Host to bind to
        port: Port to listen on
        debug: Whether to run in debug mode
    """
    logger.info(f"Starting EmailQA ActionRequiredLogger HTTP Server...")
    logger.info(f"Server URL: http://{host}:{port}")
    
    # Show API endpoint info if available
    if hasattr(action_logger, 'api_endpoint'):
        logger.info(f"API endpoint: {action_logger.api_endpoint}")
    else:
        logger.info(f"API Mode: {'Test Client' if action_logger.use_test_client else 'HTTP Requests'}")
    
    logger.info("Available endpoints:")
    logger.info("  - POST /api/mcp/action_required_logger")
    logger.info("  - GET /api/mcp/check_health")
    logger.info("  - GET /api/mcp/tools")
    
    http_app.run(host=host, port=port, debug=debug)

if __name__ == "__main__":
    import sys
    
    # Check if we should run in HTTP mode
    http_mode = '--http' in sys.argv
    
    if http_mode:
        # Extract host and port from command line arguments
        host = 'localhost'
        port = 8080
        debug = '--debug' in sys.argv
        
        for i, arg in enumerate(sys.argv):
            if arg == '--host' and i + 1 < len(sys.argv):
                host = sys.argv[i + 1]
            elif arg == '--port' and i + 1 < len(sys.argv):
                port = int(sys.argv[i + 1])
        
        # Run with HTTP transport
        run_http_server(host=host, port=port, debug=debug)
    else:
        # Run the MCP server with stdio transport
        logger.info("Starting EmailQA ActionRequiredLogger MCP Server...")
        logger.info(f"API endpoint: {action_logger.api_endpoint}")
        logger.info("Transport: stdio")
        
        mcp.run()